#include "sbwindow.h"
#include <allegro5/allegro_native_dialog.h>
#include <iostream>
#include "scrollskin.h"
#include "scrollbar.h"
#include "app.h"
#include "patternview.h"
#include "keybindings.h"
#include "transportview.h"
#include "font.h"
#include "tabview.h"
#include "songview.h"
#include "instrumentview.h"
#include "songattrview.h"
using namespace std;

SbWindow::SbWindow(App *pApp, ALLEGRO_DISPLAY *pDisplay) 
: MainWindow(pDisplay), m_pPatternView(NULL), m_pApp(pApp), m_pTransport(NULL),
  m_pMainTabView(NULL), m_pSongView(NULL), 
  m_pBottomTabView(NULL), m_pInstrumentView(NULL), 
  m_pSongAttView(NULL), m_pPianoView(NULL) {
     
     m_pFont = new Font("images/7x14.png", 7, 14);

     // create views after allegro is initialized in MainWindow
     // use default Rect for now -  rects will be updated in setRect()
     m_pTransport = new TransportView(m_pFont, Point(), m_pApp);
     // create pattern view
     m_pPatternView = new PatternView(m_pApp, Rect(), m_pFont);
     // create song view
     m_pSongView = new SongView(pApp, Rect(), m_pFont);
     // create bottom tab view
     m_pBottomTabView = new TabView(Rect(), m_pFont);
     m_pInstrumentView = new InstrumentView(Rect(), m_pApp);
     m_pBottomTabView->createTab("instruments", m_pInstrumentView);
     m_pSongAttView = new SongAttrView(Rect(), m_pFont);
     m_pBottomTabView->createTab("song", m_pSongAttView);
     m_pPianoView = new View(Rect(), m_pFont);
     m_pBottomTabView->createTab("piano", m_pPianoView);
     m_pBottomTabView->setActiveTab("instruments");
     // create main tab view
     m_pMainTabView = new TabView(Rect(), m_pFont);
     m_pMainTabView->createTab("pattern", m_pPatternView);
     m_pMainTabView->createTab("arrangement", m_pSongView);
     m_pMainTabView->setActiveTab("pattern");
     // store in views vector for easier handling
     m_views.push_back(m_pTransport);
     m_views.push_back(m_pMainTabView);
     m_views.push_back(m_pBottomTabView);
     // set rect - this sets all the children view rects correctly
     setRect(m_rect);
}

SbWindow::~SbWindow() {
     al_destroy_display(m_pDisplay);
     delete m_pMainTabView;
     delete m_pSongView;
     delete m_pPatternView;
     delete m_pBottomTabView;
     delete m_pInstrumentView;
     delete m_pSongAttView;
     delete m_pPianoView;
     delete m_pTransport;
}

// draw the whole window
void SbWindow::setRect(Rect r) {
     int h = al_get_display_height();
     int w = al_get_display_width();
     Rect tr = m_pTransport->rect();
     m_pTransport->setStart(Point(w - tr.width(),0));
     m_pBottomTabView->setRect(Rect(0,h - SbWindow::BottomHeight,
				    w,SbWindow::BottomHeight));
     m_pMainTabView->setRect(Rect(0,tr.height(),
				  w,h - tr.height() - SbWindow::BottomHeight));
     // force all views to repaint
     paint(true);
}

void SbWindow::keyDown(int keycode, int modifiers, int unichar) {
     KeyBindings *pKeys = m_pApp->keyBindings();
     // quit
     if (keycode == ALLEGRO_KEY_ESCAPE) {
	  blur();
	  m_quit = true;
     // save
     } else if (keycode == ALLEGRO_KEY_S && modifiers & ALLEGRO_KEYMOD_CTRL) {
	  blur(); // all views loose focus - in case we're editing names, etc
	  // get file to save to if it's not set
	  if (m_pApp->song()->fileName().empty() || 
	      (modifiers & ALLEGRO_KEYMOD_SHIFT)) {
	       ALLEGRO_NATIVE_DIALOG *pDialog=NULL;
	       pDialog = al_create_native_file_dialog(al_create_path("."), 
						      "Save song", "*.*", 
						      ALLEGRO_FILECHOOSER_SAVE);
	       al_show_native_file_dialog(pDialog);
	       const ALLEGRO_PATH *pPath=NULL;
	       pPath = al_get_native_file_dialog_path(pDialog, 0);
	       if (!pPath)
		    return;
	       string fileName(al_path_cstr(pPath, ALLEGRO_NATIVE_PATH_SEP));
	       m_pApp->song()->setFileName(fileName);
	  }
	  m_pApp->song()->save();
     // load
     } else if (keycode == ALLEGRO_KEY_O && modifiers & ALLEGRO_KEYMOD_CTRL) {
	  blur();
	  ALLEGRO_NATIVE_DIALOG *pDialog=NULL;
	  pDialog = al_create_native_file_dialog(al_create_path("."), 
						 "Open song", "*.*", 
						 ALLEGRO_FILECHOOSER_FILE_MUST_EXIST);
	  al_show_native_file_dialog(pDialog);
	  const ALLEGRO_PATH *pPath=NULL;
	  pPath = al_get_native_file_dialog_path(pDialog, 0);
	  if (!pPath)
	       return;
	  string fileName(al_path_cstr(pPath, ALLEGRO_NATIVE_PATH_SEP));
	  m_pApp->song()->setFileName(fileName);
	  m_pApp->song()->load();
	  m_pApp->patternEditor()->reset();
	  m_pApp->player()->updateTempo();
	  m_needPaint = true;
     }
     // check for key grab
     for (unsigned int i=0; i<m_views.size(); i++) {
	  if (m_views[i]->grabKeys()) {
	       m_views[i]->keyDown(keycode, modifiers, unichar);
	       return;
	  }
     }
     if (pKeys->keyAction(keycode, modifiers) == KeyBindings::TogglePlay) {
	  if (!m_pApp->player()->playing()) {
	       if (m_pPatternView->visible()) {
		    m_pApp->player()->setMode(Player::PlayPattern);
		    int item = m_pApp->patternEditor()->curSongItemNum();
		    m_pApp->player()->setSongItemNum(item);
		    m_pApp->player()->setRow(-1);
	       } else {
		    m_pApp->player()->setMode(Player::PlaySong);
		    m_pApp->player()->setSongItemNum(0);
		    m_pApp->player()->setRow(-1);
	       }
	  }
	  m_pApp->player()->togglePlaying();
     } else {
	  MainWindow::keyDown(keycode, modifiers, unichar);
     }
}
